package graph.algorithm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import graph.Edge;
import graph.Graph;
import graph.Node;

public class Multiplyer implements Transformer {
	private int n;
	private boolean circle;
	public Multiplyer(int n, boolean circle) {
		this.n = n;
		this.circle = circle;
	}
	@Override
	public <T,V> void transform(Graph<T,V> graph) {
		HashMap<Node<T>, Node<T>> nextMap = new HashMap<Node<T>, Node<T>>();
		ArrayList<Edge<T,V>> edges = new ArrayList<Edge<T,V>>();
		for (int i=0 ; i<graph.getNodes().size() ; i++) {
			Node<T> node = graph.getNodes().get(i);
			Node<T> first = node;
			for (int j=1 ; j<n ; j++) {
				Node<T> next = node.clone();
				adjustPos(next);
				nextMap.put(node, next);
				node = next;
			}
			if (circle) {
				Edge<T,V> newEdge = new Edge<T,V>(node, first);
				edges.add(newEdge);
			}
		}
		graph.getNodes().addAll(nextMap.values());
		for (Edge<T,V> edge : graph.getEdges()) {
			for (Node<T> a=edge.a, b=edge.b ; ; ) {
				a = nextMap.get(a);
				b = nextMap.get(b);
				if (a == null) break;
				Edge<T,V> newEdge = new Edge<T,V>(a, b);
				edges.add(newEdge);
			}
		}
		for (Map.Entry<Node<T>, Node<T>> e : nextMap.entrySet()) {
			Edge<T,V> newEdge = new Edge<T,V>(e.getKey(), e.getValue());
			edges.add(newEdge);
		}
		graph.getEdges().addAll(edges);
	}
	private static void adjustPos(Node<?> node) {
		node.pos.x += Math.random();
		node.pos.y += Math.random();
	}
}
